const crypto = require('crypto');
const axios = require('axios');
const { Buffer } = require('buffer');
//讯飞开放平台应用信息
const apiKey = 'b67d9f8f7deac5f606a85150f985cee6';
const apiSecret = 'NmJiNzdkZGQxNzg0NGNjM2EyNDM5NjRj';
const appId = '72be4bef';

// 云对象教程: https://uniapp.dcloud.net.cn/uniCloud/cloud-obj
// jsdoc语法提示教程：https://ask.dcloud.net.cn/docs/#//ask.dcloud.net.cn/article/129
const ws = uniCloud.webSocketServer();

// 生成RFC1123格式的时间戳
function getRFC1123Date() {
    const now = new Date();
    return now.toUTCString();
}

// 生成签名
function generateSignature(signatureOrigin, apiSecret) {
    const hmac = crypto.createHmac('sha256', apiSecret);
    hmac.update(signatureOrigin);
    return hmac.digest('base64');
}

// 生成鉴权字符串
function generateAuthorization(apiKey, signature) {
    const authorizationOrigin = `api_key="${apiKey}",algorithm="hmac-sha256",headers="host date request-line",signature="${signature}"`;
    return Buffer.from(authorizationOrigin).toString('base64');
}

// 创建任务请求
async function createTask(text) {
    const host = 'api-dx.xf-yun.com';
    const date = getRFC1123Date();
    const requestLine = 'POST /v1/private/dts_create HTTP/1.1';
    const signatureOrigin = `host: ${host}\ndate: ${date}\n${requestLine}`;
    const signature = generateSignature(signatureOrigin, apiSecret);
    const authorization = generateAuthorization(apiKey, signature);
     const encodedText = Buffer.from(text).toString('base64')
    const url = `https://${host}/v1/private/dts_create?host=${host}&date=${encodeURIComponent(date)}&authorization=${authorization}`;
    const data = {
        header: {
            app_id: appId
        },
        parameter: {
            dts: {
                vcn: 'x4_mingge',
                language: 'zh',
                speed: 50,
                volume: 50,
                pitch: 50,
                rhy: 1,
                audio: {
                    encoding: 'lame',
                    sample_rate: 16000
                },
                pybuf: {
                    encoding: 'utf8',
                    compress: 'raw',
                    format: 'plain'
                }
            }
        },
        payload: {
            text: {
                encoding: 'utf8',
                compress: 'raw',
                format: 'plain',
                text:encodedText
            }
        }
    };

    try {
        const response = await axios.post(url, data);
        return response.data;
    } catch (error) {
        console.error('创建任务失败:', error.response? error.response.data : error.message);
    }
}

// 查询任务请求
async function queryTask(taskId) {
    const host = 'api-dx.xf-yun.com';
    const date = getRFC1123Date();
    const requestLine = 'POST /v1/private/dts_query HTTP/1.1';
    const signatureOrigin = `host: ${host}\ndate: ${date}\n${requestLine}`;
    const signature = generateSignature(signatureOrigin, apiSecret);
    const authorization = generateAuthorization(apiKey, signature);

    const url = `https://${host}/v1/private/dts_query?host=${host}&date=${encodeURIComponent(date)}&authorization=${authorization}`;
    const data = {
        header: {
            app_id: appId,
            task_id: taskId
        }
    };

    // try {
    //     const response = await axios.post(url, data);
    //     return response.data;
    // } catch (error) {
    //     console.error('查询任务失败:', error.response? error.response.data : error.message);
    // }
}


// 示例用法




// 这里如果不需要使用 uniPush，可以删除以下代码
// const uniPush = uniCloud.getPushManager({
// 	appId: "__UNI__180DEE6"
// })
function getGridCode (location){
	      const lonPart = (Math.round(location.longitude * 1000) / 1000).toFixed(3);
	      const latPart = (Math.round(location.latitude * 1000) / 1000).toFixed(3);
	      return `${lonPart}_${latPart}`;
	  }
function   getSurroundingGrids(centerGrid, radius) {
        const [lonStr, latStr] = centerGrid.split('_');
        let centerLon = parseFloat(lonStr);
        let centerLat = parseFloat(latStr);

        const grids = new Set();
        for (let x = -radius; x <= radius; x++) {
            for (let y = -radius; y <= radius; y++) {
                let targetLon = centerLon + x * 0.001;
                let targetLat = centerLat + y * 0.001;

                // 处理经度环绕
                if (targetLon < -180) targetLon += 360;
                else if (targetLon > 180) targetLon -= 360;

                // 处理纬度边界
                targetLat = Math.max(-90, Math.min(90, targetLat));
				const location={longitude:targetLon,latitude:targetLat}

                grids.add(getGridCode(location));
            }
        }
        return Array.from(grids);
    }	  
	  
module.exports = {
    webSocketServer: ws,
    _before: function () {
        // 全局未捕获异常处理程序
        process.on('uncaughtException', (err) => {
            console.error('全局异常:', err);
            // 可以在这里添加更详细的错误处理逻辑，例如记录到日志文件或发送错误通知
        });
    },
    /**
     * WebSocket 连接成功事件处理方法
     * @param {Object} event - 事件信息
     * @param {Object} context - 云函数运行上下文
     */
    async _onWebsocketConnection(event, context) {
        console.log("WebSocket连接成功", event);
    },
    /**
     * 接收到 WebSocket 消息事件处理方法
     * @param {Object} event - 事件信息，包含消息内容
     * @param {Object} context - 云函数运行上下文
     */
    async _onWebsocketMessage(event, context) {
    },
    /**
     * WebSocket 连接断开事件处理方法
     * @param {Object} event - 事件信息
     * @param {Object} context - 云函数运行上下文
     */
    async _onWebsocketDisConnection(event, context) {
        console.log("WebSocket连接断开", event);
        // 在这里添加连接断开后的逻辑，例如更新用户在线状态等
    },
    /**
     * WebSocket 发生错误事件处理方法
     * @param {Object} event - 事件信息
     * @param {Object} context - 云函数运行上下文
     */
    async _onWebsocketError(event, context) {
        console.error("错误详情:", event.errorMessage);
        // 在这里添加错误处理逻辑，例如记录错误日志等
    },

    // 1. 生成格子标识函数



    // 2. 获取周围格子函数
    async updateUserPosition(userId, location) {
        const db = uniCloud.databaseForJQL();
        const grid =getGridCode(location.longitude,location.latitude);

        // 检查集合是否存在，可根据实际情况添加相应逻辑
        const collection = db.collection('opendb-poi');
         try {
            await collection.doc(userId).set({
                userId,
                location,
                grid,
                updatedAt: Date.now()
            });
        } catch (error) {
            console.error('更新用户位置时出错:', error);
            // 可以在这里添加更详细的错误处理逻辑，例如回滚操作或发送通知
        }
    },
    // 3. 用户位置更新示例
 
    // 4. 查询附近信息示例
/**
     * WebSocket 连接断开事件处理方法
     * @param {Object} location -地理坐标
     * @param {Number} quantity - 请求的跳过条数
	 * @param {Number} radius-请求的格子跨度，一格是相临的约110米
     */
    async getNearbyInfo(location,quantity,radius) {
	
        const db = uniCloud.database();
        const centerGrid = getGridCode(location);
        const surroundingGrids = getSurroundingGrids(centerGrid, radius);
	
	    const poiCollection = db.collection('opendb-poi');
        const messageCollection = db.collection('message_public');

        let onlineUsers;
        let chatMessages;

        try {
            // 查询在线用户
            onlineUsers = await poiCollection
              .where({
                    grid: db.command.in(surroundingGrids)
                })
              .get();
        } catch (error) {
            console.error('查询在线用户时出错:', error);
            // 可以在这里添加更详细的错误处理逻辑，例如返回默认值或发送通知
        }

        try {
            // 查询公共聊天记录（最近7天）
            chatMessages = await messageCollection
              .where({
                    grid: db.command.in(surroundingGrids),
                    timestamp: db.command.gte(Date.now() - 7 * 24 * 3600 * 1000)
                })
              .orderBy('timestamp', 'desc')
			  .limit(20)
			  .skip(quantity)
              .get();
        } catch (error) {
            console.error('查询公共聊天记录时出错:', error);
            // 可以在这里添加更详细的错误处理逻辑，例如返回默认值或发送通知
        }

        return { onlineUsers,chatMessages };
    },
//这是收藏列表
 async favorite(data) {
   const db = uniCloud.database()
   const _ = db.command
   console.log('data((()))',data)
   try {
     if (data.action === "add") {
       // 构建添加的数据
       const addData = {
         favorite_id: data.favorite_id || getGridCode(data.location),
         type: data.type,
         name: data.name,
         location: data.location,
         createTime: new Date().getTime() // 添加创建时间
       }
       
       // 检查用户记录是否存在
       const userRes = await db.collection('linli-user').where({
         userId: data.userId,
		 
       }).field({
		   favorite:true
	   }).get()
       console.log('++++++++++',userRes)
       if (userRes.data.length > 0) {
         // 用户记录已存在，检查收藏是否已存在
         const userData = userRes.data[0]
         const favoriteList = userData.favorite || []
         
         const index = favoriteList.findIndex(item => item.favorite_id === addData.favorite_id)
		 console.log('...............',index);
         
         if (index === -1) {
           // 收藏不存在，添加到列表
          const res= await db.collection('linli-user').where({
             userId: data.userId
           }).update({
             favorite: _.push(addData)
           })
           return { success: true, message: '添加收藏成功', data:res }
         } else {
           return { success: false, message: '该项目已在收藏列表中' }
         }
       } 
     }
     
     if (data.action === "remove") {
       // 获取当前收藏列表
       const userRes = await db.collection('linli-user').where({
         userId: data.userId
       }).field({
         favorite: true
       }).get();
       
       if (userRes.data.length === 0) {
         return { success: false, message: '用户记录不存在' };
       }
       
       // 过滤掉要删除的收藏项
       const newFavorites = userRes.data[0].favorite.filter(
         item => item.favorite_id !== data.favorite_id
       );
       
       // 直接替换整个数组
       const updateRes = await db.collection('linli-user').where({
         userId: data.userId
       }).update({
         favorite: newFavorites
       });
       
       return { success: true, message: '删除收藏成功' };
     }
     
     // 无效操作类型
     return { success: false, message: '无效的操作类型' }
     
   } catch (error) {
     console.error('收藏操作失败:', error)
     return { success: false, message: '服务器内部错误', error }
   }
 }
}